/*
 * Copyright (c) Huawei Technologies Co., Ltd. 2023-2023. All rights reserved.
 */

import path from 'path';

import log4js, { Configuration, Level, Logger } from 'log4js';

import { configure, HvigorLogger } from '../../log/hvigor-log.js';
import { MetricLogType } from '../../metrics/event/log-event.js';
import { DAEMON_LOG_PATH } from '../const/daemon-const.js';

const daemonConfiguration: Configuration = {
  appenders: {
    'daemon-client-file': {
      type: 'fileSync',
      filename: path.resolve(DAEMON_LOG_PATH, 'daemon-client.log'),
      maxLogSize: 10 * 1024 * 1024,
      backups: 2,
      encoding: 'utf-8',
    },
  },
  categories: {
    'daemon-client': { appenders: ['daemon-client-file', 'just-debug', 'just-info', 'just-wrong'], level: 'debug' },
  },
};

export class HvigorDaemonClientLogger extends HvigorLogger {
  private readonly _daemonClientFileLogger: Logger;

  protected constructor(category?: string) {
    super('default');
    this._daemonClientFileLogger = log4js.getLogger(category);
  }

  /**
   * 获取对于类别的HvigorLogger实例
   *
   * @param {string} category 默认是default
   * @return {HvigorLogger}
   */
  public static getLogger(category?: string): HvigorDaemonClientLogger {
    return this.getInstance(HvigorDaemonClientLogger, category);
  }

  log(level: Level | string, ...args: unknown[]): void {
    this.createLogEventByDurationId(level, MetricLogType.INFO, ...args);
    this._daemonClientFileLogger.log(level, ...args);
  }

  debug(message: unknown, ...args: unknown[]): void {
    this.createLogEventByDurationId(message, MetricLogType.DEBUG, ...args);
    this._daemonClientFileLogger.debug(message, ...args);
  }

  info(message: unknown, ...args: unknown[]): void {
    this.createLogEventByDurationId(message, MetricLogType.INFO, ...args);
    this._daemonClientFileLogger.info(message, ...args);
  }

  warn(message: unknown, ...args: unknown[]): void {
    if (message === undefined || message === '') {
      return;
    }
    this.createLogEventByDurationId(message, MetricLogType.WARN, ...args);
    this._daemonClientFileLogger.warn(message, ...args);
  }

  error(message: unknown, ...args: unknown[]): void {
    this.createLogEventByDurationId(message, MetricLogType.ERROR, ...args);
    this._daemonClientFileLogger.error(message, ...args);
  }

  clientErrorLink(): void {
    this.error(`A log of client process can be found in: ${path.resolve(DAEMON_LOG_PATH, 'daemon-client.log')}`);
  }

  daemonErrorLink(daemonPid: number): void {
    this.error(`A log of daemon process can be found in: ${path.resolve(DAEMON_LOG_PATH, `daemon-${daemonPid}.log`)}`);
  }

  clientWarnLink(): void {
    this.warn(`A log of client process can be found in: ${path.resolve(DAEMON_LOG_PATH, 'daemon-client.log')}`);
  }

  daemonWarnLink(daemonPid: number): void {
    this.warn(`A log of daemon process can be found in: ${path.resolve(DAEMON_LOG_PATH, `daemon-${daemonPid}.log`)}`);
  }
}

export function configureDaemonClient() {
  configure(daemonConfiguration);
}
